From aac2d5999f48ddf0f5a6ca0804037e56f5d8fde5 Mon Sep 17 00:00:00 2001 From: "robertlipe@gmail.com" Date: Sun, 4 Sep 2011 21:03:14 +0000 Subject: [PATCH] Completely change the way language handling works in the GUI. git-svn-id: http://gpsbabel.googlecode.com/svn/trunk@4085 f51c46e8-681c-474f-0cfe-069cfd0219fb --- gpsbabel/gui/main.cpp | 33 +---------- gpsbabel/gui/mainwindow.cpp | 107 +++++++++++++++++++++++++++++++++++- gpsbabel/gui/mainwindow.h | 13 +++++ 3 files changed, 119 insertions(+), 34 deletions(-) diff --git a/gpsbabel/gui/main.cpp b/gpsbabel/gui/main.cpp index c1dc56a21..0e50b6ed7 100644 --- a/gpsbabel/gui/main.cpp +++ b/gpsbabel/gui/main.cpp @@ -25,7 +25,6 @@ #include #include #include -#include #include #include "mainwindow.h" @@ -41,33 +40,6 @@ const char *pathSeparator = ":"; #include #endif -//------------------------------------------------------------------------ -static void installTranslation(QApplication *app, const QString &nm) -{ - QTranslator *xlator = new QTranslator(); - - xlator->load(QLibraryInfo::location(QLibraryInfo::TranslationsPath) + "/" + nm + QLocale::system().name()); - - xlator->load(nm + QLocale::system().name()); - -#if defined (Q_OS_MAC) - CFURLRef pluginRef = CFBundleCopyBundleURL(CFBundleGetMainBundle()); - CFStringRef macPath = CFURLCopyFileSystemPath(pluginRef, - kCFURLPOSIXPathStyle); - QString pathPtr(CFStringGetCStringPtr(macPath, CFStringGetSystemEncoding())); - pathPtr += "/Contents/MacOS/lang/" + nm; - // pathPtr += QLocale::system().name().left(2); - pathPtr += QLocale::system().name(); - - xlator->load(pathPtr); - -#endif - - app->installTranslator(xlator); -} - -//------------------------------------------------------------------------ - //------------------------------------------------------------------------ int main(int argc, char**argv) { @@ -81,10 +53,6 @@ int main(int argc, char**argv) strcpy(newPathEnv, newPath.toStdString().c_str()); putenv(newPathEnv); - installTranslation(app, "qt_"); - installTranslation(app, "gpsbabelfe_"); - installTranslation(app, "gpsbabel_"); - QCoreApplication::setOrganizationName("GPSBabel"); QCoreApplication::setOrganizationDomain("gpsbabel.org"); QCoreApplication::setApplicationName("GPSBabel"); @@ -92,5 +60,6 @@ int main(int argc, char**argv) MainWindow mainWindow(0); mainWindow.show(); app->exec(); + return 0; } diff --git a/gpsbabel/gui/mainwindow.cpp b/gpsbabel/gui/mainwindow.cpp index d8f172dec..42c828c6f 100644 --- a/gpsbabel/gui/mainwindow.cpp +++ b/gpsbabel/gui/mainwindow.cpp @@ -204,6 +204,9 @@ MainWindow::MainWindow(QWidget* parent): QMainWindow(parent) ui.outputWindow->setReadOnly(true); + // Start up in the current system language. + loadLanguage(QLocale::system().name()); + createLanguageMenu(); //--- Restore from registry restoreSettings(); @@ -228,6 +231,106 @@ MainWindow::~MainWindow() if (upgrade) delete upgrade; } +//------------------------------------------------------------------------ +// Dynamic language switching courtesy of +// http://developer.qt.nokia.com/wiki/How_to_create_a_multi_language_application +// We create the menu entries dynamically, dependant on the existing +// translations. +void MainWindow::createLanguageMenu(void) +{ + QActionGroup* langGroup = new QActionGroup(ui.menuHelp); + langGroup->setExclusive(true); + connect(langGroup, SIGNAL(triggered(QAction *)), this, SLOT(slotLanguageChanged(QAction *))); + + // format systems language + QString defaultLocale = QLocale::system().name(); // e.g. "de_DE" + defaultLocale.truncate(defaultLocale.lastIndexOf('_')); // e.g. "de" + + langPath = QApplication::applicationDirPath(); + langPath.append("/translations"); +//fprintf(stderr, "Looking in %s\n", qPrintable(langPath)); + QDir dir(langPath); + QStringList fileNames = dir.entryList(QStringList("*.qm")); + + for (int i = 0; i < fileNames.size(); ++i) { + // get locale extracted by filename + QString locale; + locale = fileNames[i]; // "TranslationExample_de.qm" + locale.truncate(locale.lastIndexOf('.')); // "TranslationExample_de" + locale.remove(0, locale.indexOf('_') + 1); // "de" + + QString lang = QLocale::languageToString(QLocale(locale).language()); + + QAction *action = new QAction(lang, this); + action->setCheckable(true); + action->setData(locale); + + ui.menuHelp->addAction(action); + langGroup->addAction(action); + + // set default translators and language checked + if (defaultLocale == locale) { + action->setChecked(true); + } + } +} + +//------------------------------------------------------------------------ +// Called every time, when a menu entry of the language menu is called +void MainWindow::slotLanguageChanged(QAction* action) +{ + if (0 != action) { + // load the language dependant on the action content. + loadLanguage(action->data().toString()); + } +} + +void switchTranslator(QTranslator& translator, const QString& filename) +{ + // remove the old translator + qApp->removeTranslator(&translator); + + // load the new translator + if (translator.load(filename)) + qApp->installTranslator(&translator); +} + +void MainWindow::loadLanguage(const QString& rLanguage) +{ + if (currLang != rLanguage) { + currLang = rLanguage; + QLocale locale = QLocale(currLang); + QLocale::setDefault(locale); + QString languageName = QLocale::languageToString(locale.language()); + switchTranslator(translator, QString("gpsbabelfe_%1.qm").arg(rLanguage)); + switchTranslator(translatorCore, QString("gpsbabel__%1.qm").arg(rLanguage)); + switchTranslator(translatorQt, QString("qt_%1.qm").arg(rLanguage)); + } +} + +void MainWindow::changeEvent(QEvent* event) +{ + if (0 != event) { + switch(event->type()) { + // This event is sent if a translator is loaded. + case QEvent::LanguageChange: + ui.retranslateUi(this); + break; + // This event is sent if the system language changes. + case QEvent::LocaleChange: + { + QString locale = QLocale::system().name(); + locale.truncate(locale.lastIndexOf('_')); + loadLanguage(locale); + } + break; + default: + break; + } + } + + QMainWindow::changeEvent(event); +} //------------------------------------------------------------------------ void MainWindow::loadInputDeviceNameCombo(const QString &format) @@ -535,7 +638,7 @@ void MainWindow::loadFormats() "Check that the backend program \"gpsbabel\" is properly installed " "and is in the current PATH\n\n" "This program cannot continue.")); - exit(1); + exit(1); } if (inputFileFormatIndices().size() == 0 || inputDeviceFormatIndices().size() == 0 || @@ -954,7 +1057,7 @@ void MainWindow::closeActionX() bd.runCount++; QDateTime now = QDateTime::currentDateTime(); - if((bd.runCount > 5) && (bd.donateSplashed.daysTo(now) > 30)) { + if ((bd.runCount > 5) && (bd.donateSplashed.daysTo(now) > 30)) { Donate donate(0); if (bd.donateSplashed.date() == QDate(2010,1,1)) donate.showNever(false); diff --git a/gpsbabel/gui/mainwindow.h b/gpsbabel/gui/mainwindow.h index 9c449cfe9..cf1a283c6 100644 --- a/gpsbabel/gui/mainwindow.h +++ b/gpsbabel/gui/mainwindow.h @@ -28,6 +28,8 @@ #include "babeldata.h" #include "upgrade.h" +#include + class MainWindow: public QMainWindow { Q_OBJECT @@ -36,6 +38,7 @@ class MainWindow: public QMainWindow { MainWindow(QWidget* parent); ~MainWindow(); + private: Ui_MainWindow ui; QList formatList; @@ -46,9 +49,16 @@ private: AllFiltersData filterData; BabelData bd; bool fmtChgInterlock; + QTranslator translator; // translation for the GUI. + QTranslator translatorCore; // translation for the core application. + QTranslator translatorQt; // translations for Qt. + QString currLang; // currently loaded language. + QString langPath; // Path of language files. This is always fixed to /languages. private: void loadFormats(); + void loadLanguage(const QString& rLanguage); + void createLanguageMenu(); QString filterForFormat(int idx); QString ensureExtensionPresent(const QString &nanme, int idx); QString findBabelVersion(); @@ -89,6 +99,7 @@ private: protected: void closeEvent(QCloseEvent*); + void changeEvent(QEvent*); private slots: void aboutActionX(); @@ -116,6 +127,8 @@ protected: void visitWebsiteActionX(); void resetFormatDefaults(); void upgradeCheckActionX(); + void slotLanguageChanged(QAction* action); + }; -- 2.30.2